package cate.game.role.pvp.pointrace;

import cate.common.table.d.GDGuild;
import cate.common.table.d.GDNotice;
import cate.game.chat.ChatContentParam;
import cate.game.framework.advanced.AdvancedByteAttributes;
import cate.game.play.fighter.HeroFighter;
import cate.game.play.proce.play.PlayPO;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.res.guild.po.GuildLogDetailPO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import org.springframework.util.CollectionUtils;

import java.util.*;

@NoteClass(value = "积分赛战绩")
public class PointRaceMark extends RoleDependent {
    @NoteField("历史最前排名")
    public int maxRank;

    @NoteField("历史最高积分")
    public long maxPoints;

    @NoteField("总胜场")
    public int winTimes;

    @NoteField("总挑战次数")
    public int fightTimes;

    @NoteField("最大伤害")
    public long maxDamage;

    @NoteField("最大连胜次数")
    public int serialWinTimes;

    @NoteField("当前连胜次数")
    public int curSerialWinTimes;

    @NoteField("mvp英雄次数")
    @JsonIgnore
    public Map<Integer, Integer> mvpHero;

    @NoteField("英雄使用次数")
    public Map<String, Integer> heroUses;

    @NoteField("mvp英雄id")
    public int mvpHeroId;

    @NoteField("flag操作")
    @JsonIgnore
    public AdvancedByteAttributes attributes;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (mvpHero == null) {
            mvpHero = new HashMap<>();
        }
        if (heroUses == null) {
            heroUses = new HashMap<>();
        }

        if (Objects.isNull(attributes)) {
            this.attributes = AdvancedByteAttributes.of((byte) 0);
        }
    }


    @Override
    public void onEnter() {
        super.onEnter();
        fixHeroTid();
        fixTimes();
    }

    static final int FIX_HERO_TID = 1;

    private void fixHeroTid() {
        if (!attributes.hasAttribute(FIX_HERO_TID)) {
            if (!CollectionUtils.isEmpty(this.heroUses)) {
                this.heroUses.clear();
            }

            if (!CollectionUtils.isEmpty(this.mvpHero)) {
                this.mvpHero.clear();
            }
            this.mvpHeroId = 0;

            attributes.setAttribute(FIX_HERO_TID);
        }
    }

    static final int FIX_TIMES = 2;

    private void fixTimes() {
        if (!attributes.hasAttribute(FIX_TIMES)) {
            if (this.winTimes > this.fightTimes) {
                this.winTimes = this.fightTimes;
            }
            if (this.serialWinTimes < this.winTimes) {
                this.serialWinTimes = this.winTimes;
            }

            if (this.curSerialWinTimes > this.serialWinTimes) {
                this.curSerialWinTimes = this.serialWinTimes;
            }

            attributes.setAttribute(FIX_TIMES);
        }
    }

    private void noticeGuild(ChatContentParam name, ChatContentParam times) {
        if (role.getRes().guild.checkGuild().ok()) {
            role.getRes().guild.getGuild().record.addRecord(
                    new GuildLogDetailPO(GDGuild.log.POINT_RACE_CONTINUE_WIN, name, times)
            );
        }
    }

    public void updateMark(int rank, long points) {
        if (maxRank <= 0) {
        } else {
            this.maxRank = Math.min(maxRank, rank);
        }
        this.maxRank = rank;
        this.maxPoints = Math.max(maxPoints, points);
    }

    public void updateMark(boolean win, PlayPO play) {
        if (win) {
            // 连胜次数+1
            this.winTimes += 1;
            this.curSerialWinTimes += 1;
        } else {
            this.curSerialWinTimes = 0;
        }

        fightTimes += 1;
        if (curSerialWinTimes > serialWinTimes) {
            serialWinTimes = curSerialWinTimes;
        }
        // 最大伤害
        int mvpHeroTid = 0;
        long mvpHeroX = 0, totalDamage = 0;
        for (HeroFighter hero : play.teamEnd.a.getAllHero()) {
            totalDamage += hero.performance.damage;
//            if (hero.performance.damage > mvpHeroDamage) {
//                mvpHeroTid = hero.heroTid;
//                mvpHeroDamage = hero.performance.damage;
//            }

            // 当前英雄系数
            long currentHeroX = hero.performance.damage * 5 // 输出 * 5
                    + hero.performance.heal * 2  // 治疗 * 2
                    + hero.performance.hurt * 3; // 承伤 * 3

            if (currentHeroX > mvpHeroX) {
                mvpHeroX = currentHeroX;
                mvpHeroTid = hero.heroTid;
            }

            heroUses.putIfAbsent(String.valueOf(hero.protoId), 0);
            heroUses.put(String.valueOf(hero.protoId), heroUses.get(String.valueOf(hero.protoId)) + 1);
        }
        if (totalDamage >= maxDamage) {
            maxDamage = totalDamage;
        }
        if (mvpHeroTid != 0) {
            // mvp英雄
            mvpHero.putIfAbsent(mvpHeroTid, 0);
            mvpHero.put(mvpHeroTid, mvpHero.get(mvpHeroTid) + 1);
        }

        Optional<Map.Entry<Integer, Integer>> max = mvpHero.entrySet()
                .stream()
                .max(Comparator.comparingInt(Map.Entry::getValue));

        this.mvpHeroId = max.map(Map.Entry::getKey).orElse(0);

        role.getHistory().action.addPointRacePoints(maxPoints);
    }

    public void clearData() {
        this.curSerialWinTimes = 0;
    }
}
